using System.Web.Mvc;
using good1.ApplicationServices.Interface;
using good1.Core;
using good1.Core.Enums;
using good1.Web.Controllers.Attributes;
using good1.Web.Controllers.Extensions;
using good1.Web.Controllers.Infrastructure;
using good1.Web.Controllers.Infrastructure.Cookies;
using good1.Web.Controllers.Utility;
using good1.Web.Model;
using SharpArch.Core.PersistenceSupport;
using System.Collections.Generic;
using SharpArch.Web.NHibernate;
using SharpArch.Web.CommonValidator;
using SharpArch.Core;

namespace good1.Web.Controllers
{
    [HandleError]
    public class DonorsController : BaseController
    {
        private DonorProjectsView donor;

        public DonorsController(IRepository<Donor> donorRepository, ISecurityContextService securityContext) : base(securityContext)
        {
            Check.Require(donorRepository != null, "donorRepository may not be null");
            this.donorRepository = donorRepository;


            donor = CreateViewData<DonorProjectsView>();            
        }


        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Donor)]
        public ActionResult Account()
        {
            return View(donor);
        }

        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Donor)]
        public ActionResult Points()
        {
            return View(donor);
        }

        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Donor)]
        public ActionResult Projects()
        {
            return View(donor);
        }

        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Donor)]
        public ActionResult Settings()
        {
            return View(donor);
        }


        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Donor)]
        public ActionResult Feedback()
        {
            return View(donor);
        }

        //TODO colum, think of separating admin views into separate controller altogether
        [Transaction]
        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Nimda)]
        public ActionResult Index() {
            IList<Donor> donors = donorRepository.GetAll();
            return View(donors);
        }

        [Transaction]
        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Nimda)]
        public ActionResult Show(int id) {
            Donor donor = donorRepository.Get(id);
            return View(donor);
        }

        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Nimda)]
        public ActionResult Create() {
            return View();
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Nimda)]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(Donor donor) {
            if (donor.IsValid()) {
                donorRepository.SaveOrUpdate(donor);

                TempData["message"] = "The donor was successfully created.";
                return RedirectToAction("Index");
            }

            MvcValidationAdapter.TransferValidationMessagesTo(ViewData.ModelState,
                donor.ValidationResults());
            return View();
        }

        [Transaction]
        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Nimda)]
        public ActionResult Edit(int id) {
            Donor donor = donorRepository.Get(id);
            return View(donor);
        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Nimda)]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(int id, [ModelBinder(typeof(DefaultModelBinder))] Donor donor) {
            Donor donorToUpdate = donorRepository.Get(id);
            TransferFormValuesTo(donorToUpdate, donor);

            if (donorToUpdate.IsValid()) {
                TempData["message"] = "The donor was successfully updated.";
                return RedirectToAction("Index");
            }
            else {
                donorRepository.DbContext.RollbackTransaction();
                MvcValidationAdapter.TransferValidationMessagesTo(ViewData.ModelState, 
                    donorToUpdate.ValidationResults());
                return View(donorToUpdate);
            }
        }

        private void TransferFormValuesTo(Donor donorToUpdate, Donor donorFromForm) {
			        }

        [ValidateAntiForgeryToken]
        [Transaction]
        [AuthorizeAttributeCustom(RoleRequired = GoodRoles.Nimda)]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Delete(int id) {
            string resultMessage = "The donor was successfully deleted.";
            Donor donorToDelete = donorRepository.Get(id);

            if (donorToDelete != null) {
                donorRepository.Delete(donorToDelete);

                try {
                    donorRepository.DbContext.CommitChanges();
                }
                catch {
                    resultMessage = "A problem was encountered preventing the donor from being deleted. " +
						"Another item likely depends on this donor.";
                    donorRepository.DbContext.RollbackTransaction();
                }
            }
            else {
                resultMessage = "The donor could not be found for deletion. It may already have been deleted.";
            }

            TempData["Message"] = resultMessage;
            return RedirectToAction("Index");
        }

        private readonly IRepository<Donor> donorRepository;

    }
}
